(function () {
    const UPLOAD_BUTTON_TEXT_CONTENT = {
        'ENABLE': '上传文件夹',
        'DISABLE': '文件夹上传处理中...'
    };

    const PROGRESS_TYPE = {
        'PROCESSING': 'processing',
        'UPLOAD': 'upload'
    };

    // 显示提示信息
    function showMessage(type, text) {
        const messageContainer = document.getElementById('messageContainer');
        const messageText = document.getElementById('messageText');

        messageContainer.className = `message ${type}`;
        messageText.innerText = text;
        messageContainer.style.display = 'block';
    }

    // 清除提示信息
    function clearMessage() {
        const messageContainer = document.getElementById('messageContainer');
        const messageText = document.getElementById('messageText');

        messageContainer.className = 'message';
        messageText.innerText = '';
        messageContainer.style.display = 'none';
    }

    // 读取并显示 localStorage 中的消息
    function displayLocalStorageMessage() {
        const messageType = localStorage.getItem('messageType');
        const messageText = localStorage.getItem('messageText');

        if (messageType && messageText) {
            showMessage(messageType, messageText);
            // 显示后清除 localStorage 中的消息
            localStorage.removeItem('messageType');
            localStorage.removeItem('messageText');
        }
    }

    // 连接到 WebSocket 服务器
    function connect() {
        const socket = new SockJS('/ws');
        const stompClient = Stomp.over(socket);
        // 设置 debug 为一个空函数以关闭控制台输出
        stompClient.debug = () => {
        };
        // 连接到 WebSocket 服务器
        stompClient.connect({}, function (frame) {
            stompClient.subscribe('/topic/uploadProgress', function (message) {
                // 获取当前页面的特定标识（可以是 URL 参数或其他唯一标识）
                const urlParams = new URLSearchParams(window.location.search);
                let requestId = urlParams.get('requestId');
                const progressMessage = JSON.parse(message.body);
                if (progressMessage.requestId === requestId) {
                    const progress = progressMessage.progress;
                    showProgress(progress, PROGRESS_TYPE.PROCESSING);
                    showUploadButton(progress);
                }
            });
        });
    }

    // 生成请求 ID
    function generateRequestId() {
        // 构建 UUID 模板字符串
        const template = ([1e7] + -1e3 + -4e3 + -8e3 + -1e11);

        // 使用正则表达式匹配模板字符串中的特定字符（0, 1, 8）
        return template.replace(/[018]/g, c =>
            // 生成随机数并进行位操作
            (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
        );
    }

    // 显示上传进度
    function showProgress(progress, type) {
        // 获取进度条元素
        const uploadProgress = document.getElementById('upload-progress');
        const processingProgress = document.getElementById('processing-progress');
        const progressContainer = document.querySelector('.progress-container');
        // 显示进度条
        progressContainer.style.display = 'block';
        if (type === PROGRESS_TYPE.PROCESSING) {
            // 显示处理进度条
            uploadProgress.value = 100;
            processingProgress.value = progress;
        } else {
            // 显示上传进度条
            uploadProgress.value = progress;
        }

        // 上传完成后隐藏进度条
        if (progress >= 100 && type === PROGRESS_TYPE.PROCESSING) {
            progressContainer.style.display = 'none';
            uploadProgress.value = 0;
            processingProgress.value = 0;
        }
    }

    // 显示上传按钮
    function showUploadButton(progress) {
        const submitButton = document.getElementById('uploadButton');
        if (progress >= 100) {
            submitButton.disabled = false;
            submitButton.textContent = UPLOAD_BUTTON_TEXT_CONTENT.ENABLE;
        } else {
            submitButton.disabled = true;
            submitButton.textContent = UPLOAD_BUTTON_TEXT_CONTENT.DISABLE;
        }
    }

    /**
     * 防抖函数（不能及时响应，此处不用）
     *
     * @param func 回调方法
     * @param wait 等待时间（毫秒）
     * @returns {(function(...[*]): void)|*}
     */
    function debounce(func, wait) {
        let timeout;
        return function (...args) {
            const context = this;
            clearTimeout(timeout);
            timeout = setTimeout(() => {
                func.apply(context, args);
            }, wait);
        };
    }

    /**
     * 节流函数
     *
     * @param func 回调方法
     * @param wait 等待时间（毫秒）
     * @returns {(function(...[*]): void)|*}
     */
    function throttle(func, wait) {
        let lastTime = 0;
        return function (...args) {
            const now = new Date();
            if (now - lastTime >= wait) {
                lastTime = now;
                func.apply(this, args);
            }
        };
    }

    /**
     * 异步上传文件
     */
    function uploadFiles(event) {
        // 清理提示信息
        clearMessage();

        const files = document.getElementById('files').files;
        const folderName = document.getElementById('folderName').value;
        const removeOldFiles = document.getElementById('removeOldFiles').checked;

        // 判断是否选择了文件，没有选择则退出处理
        if (files.length === 0) {
            showMessage('warning', '请选择要上传的文件夹');
            return null;
        }

        // 生成请求 ID，并缓存到 localStorage
        const requestId = generateRequestId();
        const newUrl = window.location.pathname + '?requestId=' + requestId;
        // 更新当前URL，不创建新历史记录
        window.history.replaceState({}, '', newUrl);
        const formData = new FormData();
        for (let i = 0; i < files.length; i++) {
            formData.append('files', files[i]);
        }
        formData.append('folderName', folderName);
        formData.append('requestId', requestId);
        formData.append('removeOldFiles', removeOldFiles);

        const submitButton = document.getElementById('uploadButton');
        submitButton.disabled = true;
        // 更改按钮文本
        submitButton.textContent = UPLOAD_BUTTON_TEXT_CONTENT.DISABLE;

        sendRequest(formData, submitButton);
    }

    // 发送异步请求
    function sendRequest(formData, submitButton) {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '/resources/uploadFolder', true);

        xhr.upload.addEventListener('progress', function (event) {
            if (event.lengthComputable) {
                const percentComplete = Math.round((event.loaded / event.total) * 100);
                showProgress(percentComplete, PROGRESS_TYPE.UPLOAD);
            }
        });

        xhr.onload = function () {
            if (xhr.status === 200) {
                localStorage.setItem('messageType', 'success');
                localStorage.setItem('messageText', '上传成功');
                window.location.href = "/resources";
            } else if (xhr.status === 401) {
                // 如果返回 401 未授权，重定向到登录页面
                window.location.href = '/login';
            } else {
                showMessage('error', '上传失败');
                submitButton.disabled = false;
                // 恢复按钮文本
                submitButton.textContent = UPLOAD_BUTTON_TEXT_CONTENT.ENABLE;
            }
        };

        xhr.onerror = function () {
            showMessage('error', '上传失败');
            submitButton.disabled = false;
            // 恢复按钮文本
            submitButton.textContent = UPLOAD_BUTTON_TEXT_CONTENT.ENABLE;
        };

        xhr.send(formData);
    }

    /**
     * 删除指定路径的资源
     * @param {string} path - 要删除的资源路径
     */
    function deleteResource(path) {
        if (confirm('确定要删除该资源吗？')) {
            // 实现文件删除逻辑
            fetch(`/api/resources/delete?path=${encodeURIComponent(path)}`, {
                method: 'DELETE'
            })
                .then(response => {
                    if (response.ok) {
                        localStorage.setItem('messageType', 'success');
                        localStorage.setItem('messageText', '删除成功');
                        const li = document.querySelector(`[data-path="${path}"]`);
                        const ul = li.nextElementSibling;
                        // 删除子目录
                        if (ul && ul.tagName === 'UL') {
                            ul.remove();
                        }
                        const parentLi = li.parentElement;
                        if (parentLi && parentLi.tagName === 'UL' && parentLi.children.length === 1) {
                            // 如果当前目录为空，则删除该目录
                            parentLi.remove();
                        } else {
                            // 否则只删除当前文件
                            li.remove();
                        }
                        showMessage('success', '删除成功');
                    } else if (response.status === 401) {
                        // 如果返回 401 未授权，重定向到登录页面
                        window.location.href = '/login';
                    } else {
                        showMessage('error', '删除失败');
                    }
                })
                .catch(error => showMessage('error', "删除文件出错:" + error));
        }
    }

    /**
     * 加载给定路径下的文件，并将其添加到指定的父元素中。
     * @param {string} path - 要加载的文件路径。
     * @param {HTMLElement} parentElement - 用于显示文件列表的父元素。
     * @param {number} level - 文件展示的缩进层级。
     */
    function loadFiles(path, parentElement, level = 0) {
        fetch(`/api/resources/list?path=${encodeURIComponent(path)}`)
            .then(response => response.json())
            .then(files => {
                files.forEach(file => {
                    const li = createFileItem(file, level);
                    parentElement.appendChild(li);
                });
            });
    }

    /**
     * 创建一个文件项元素，包括图标、文件名和操作按钮。
     * @param {Object} file - 文件信息对象。
     * @param {number} level - 文件展示的缩进层级。
     * @returns {HTMLElement} - 文件项元素。
     */
    function createFileItem(file, level) {
        const li = document.createElement("li");
        li.classList.add("file-item");
        li.dataset.path = file.fullPath;
        li.dataset.level = level;

        // 添加图标
        li.appendChild(createFileIcon(file, level));

        // 添加文件名
        li.appendChild(createFileName(file));

        // 如果是目录，添加点击事件以展开/折叠子目录
        if (file.directory) {
            li.addEventListener("click", handleDirectoryClick);
        }

        // 添加操作按钮
        li.appendChild(createActionButtons(file));

        // 添加鼠标悬停和点击事件处理程序
        li.addEventListener("mouseover", handleMouseOver);
        li.addEventListener("mouseout", handleMouseOut);
        li.addEventListener("click", handleItemClick);

        return li;
    }

    /**
     * 创建表示文件图标的元素。
     * @param {Object} file - 文件信息对象。
     * @param {number} level - 文件展示的缩进层级。
     * @returns {HTMLElement} - 表示文件图标的元素。
     */
    function createFileIcon(file, level) {
        const iconSpan = document.createElement("span");
        iconSpan.className = file.directory ? "folder-icon" : "file-icon";
        iconSpan.style.marginLeft = `${level * 20}px`;
        return iconSpan;
    }

    /**
     * 创建表示文件名的元素。
     * @param {Object} file - 文件信息对象。
     * @returns {HTMLElement} - 表示文件名的元素。
     */
    function createFileName(file) {
        const nameSpan = document.createElement("span");
        nameSpan.classList.add("file-name");
        nameSpan.textContent = file.fullPath.split('/').filter(p => p).pop();
        return nameSpan;
    }

    /**
     * 处理目录点击事件，展开或折叠子目录。
     * @param {Event} event - 点击事件。
     */
    function handleDirectoryClick(event) {
        event.stopPropagation();
        const li = this;
        // 获取当前层级信息
        const level = parseInt(li.dataset.level);

        if (li.classList.contains("expanded")) {
            li.classList.remove("expanded");
            li.nextElementSibling.classList.add("hidden");
        } else {
            li.classList.add("expanded");
            let ul = li.nextElementSibling;
            if (!ul || ul.tagName !== 'UL') {
                ul = createSubList(li, level + 1);
            }
            ul.classList.remove("hidden");
        }
    }

    /**
     * 处理鼠标悬停文件项时的事件。
     * @param {Event} event - 鼠标悬停事件。
     */
    function handleMouseOver(event) {
        this.classList.add("hover");
    }

    /**
     * 处理鼠标移出文件项时的事件。
     * @param {Event} event - 鼠标移出事件。
     */
    function handleMouseOut(event) {
        this.classList.remove("hover");
    }

    /**
     * 处理文件项点击事件，确保只有一个文件项处于高亮状态。
     * @param {Event} event - 点击事件。
     */
    function handleItemClick(event) {
        const previouslyActive = document.querySelector(".file-item.active");
        if (previouslyActive) {
            previouslyActive.classList.remove("active");
        }
        this.classList.add("active");
    }

    /**
     * 创建操作按钮的容器元素，包括下载和删除按钮。
     * @param {Object} file - 文件信息对象。
     * @returns {HTMLElement} - 操作按钮的容器元素。
     */
    function createActionButtons(file) {
        const actions = document.createElement("div");
        actions.className = "buttons";

        // 创建下载按钮
        const downloadBtn = document.createElement("button");
        downloadBtn.textContent = "下载";
        downloadBtn.className = "download";
        downloadBtn.addEventListener("click", function (event) {
            event.stopPropagation();
            downloadFile(file.fullPath);
        });
        actions.appendChild(downloadBtn);

        // 创建删除按钮（仅在用户已登录时显示）
        if (isLoggedIn) {
            const deleteBtn = document.createElement("button");
            deleteBtn.textContent = "删除";
            deleteBtn.className = "delete";
            deleteBtn.addEventListener("click", function (event) {
                event.stopPropagation();
                deleteResource(file.fullPath);
            });
            actions.appendChild(deleteBtn);
        }

        return actions;
    }

    /**
     * 创建子列表
     *
     * @param parentElement 父元素
     * @param level 列表层级
     * @returns {HTMLUListElement} 子列表
     */
    function createSubList(parentElement, level) {
        const ul = document.createElement("ul");
        ul.className = "file-tree hidden";
        parentElement.insertAdjacentElement('afterend', ul);
        loadFiles(parentElement.dataset.path, ul, level);
        return ul;
    }

    /**
     * 下载资源
     *
     * @param path 资源路径
     */
    function downloadFile(path) {
        window.location.href = '/api/resources/download?path=' + encodeURIComponent(path);
    }

    /**
     * 页面加载完毕后连接到 WebSocket 服务器
     */
    document.addEventListener('DOMContentLoaded', function () {
        connect();
        const uploadButton = document.getElementById('uploadButton');
        if (uploadButton) {
            // 节流方案
            uploadButton.addEventListener('click', throttle(uploadFiles, 200));
            // 防抖方案
            // uploadButton.addEventListener('click', debounce(uploadFiles, 200));

            // 监听键盘事件
            document.addEventListener('keydown', function (event) {
                // 检查是否按下了回车键
                if (event.key === 'Enter') {
                    // 触发按钮点击事件
                    uploadButton.click();
                }
            });
        }

        // 加载文件列表
        loadFiles("", document.getElementById("fileTree"));
    });

    /**
     * 当用户选择文件夹时清空提示信息
     * @type {HTMLElement}
     */
    const filesInput = document.getElementById('files');
    if (filesInput) {
        filesInput.addEventListener('change', function () {
            clearMessage();
        });
    }

    /**
     * 在页面加载时，检查并显示 localStorage 中的消息
     */
    window.addEventListener('load', displayLocalStorageMessage);

})();
